package com.etheart.framework.core.dao;

import java.util.List;

import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

public class Page<T>{
    private int pageSize = 10;
    private int pageNum = 1;
    private long rowCnt;

    private HibernateTemplate hibernateTemplate;
    private HibernateCallback hibernateCallback;

    public Page(HibernateTemplate hibernateTemplate, HibernateCallback callback){
        this.hibernateTemplate = hibernateTemplate;
        this.hibernateCallback = callback;
    }
    public Page(){}

    private List<T> objects;

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public Page<T> current(){
        return this;
    }

    public Page<T> prev(){
        if(pageNum == 0){
            pageNum = 1;
        }else{
            pageNum --;
        }
        objects = this.getInternalObjects();
        return this;
    }  

    public Page<T> next(){
        if(pageNum == 0){
            pageNum = 1;
        }else{
            pageNum ++;
        }
        objects = this.getInternalObjects();
        return this;
    }

    private List<T> getInternalObjects(){
        int firstResult = (pageNum-1) * pageSize;
        int maxResults = pageSize;
        ((PagedListCallback) hibernateCallback).setFirstResult(firstResult);
        ((PagedListCallback) hibernateCallback).setMaxResults(maxResults);
        return hibernateTemplate.executeFind(hibernateCallback);
    }

    public List<T> getObjects(){
        return this.objects;
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setObjects(List<T> objects) {
        this.objects = objects;
    }

    public boolean isFirstPage() {
        return pageNum == 1;
    }

    /**
     * Return if the current page is the last one.
     */
    public boolean isLastPage() {
        return pageNum == getPageCnt();
    }

    public int getPageCnt(){
        return (int) (rowCnt % pageSize == 0 ? rowCnt / pageSize : rowCnt / pageSize + 1);
    }


    public Page gotoPage(int pageNum){
        this.pageNum = pageNum;
        objects = this.getInternalObjects();
        return this;
    }

    public void refresh(){
        objects = getInternalObjects();
    }
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
    public HibernateCallback getHibernateCallback() {
        return hibernateCallback;
    }
    public void setHibernateCallback(HibernateCallback hibernateCallback) {
        this.hibernateCallback = hibernateCallback;
    }

    public void setRowCnt(long rowCnt) {
        this.rowCnt = rowCnt;
    }

    public long getRowCnt() {
        return rowCnt;
    }
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    /**
     *
     * @param count
     */
	public void remove(int count) {
		this.rowCnt = this.rowCnt - count;
		if(rowCnt%pageSize==0){
			pageNum = pageNum - 1;
		}
		refresh();
	}
}
